// 评分引擎 - 处理问卷评分逻辑
import { getAssessResult } from './schema-loader.js'
import { getFact } from './facts-manager.js'

/**
 * 评分引擎类
 */
export class ScoringEngine {
    constructor(scoreJudge, globalQues = null) {
        this.scoreJudge = scoreJudge;
        this.globalQues = globalQues;
    }

    /**
     * 计算题目得分
     * @param {Object} question - 题目对象
     * @param {*} answer - 答案
     * @returns {Object|null} 得分结果
     */
    calculateQuestionScore(question, answer) {
        // 如果问卷不需要评分，直接返回null
        if (this.globalQues.isScoring != null && !this.globalQues.isScoring) return null;
        
        if (!question.judge) return null;

        const { map, scores, score_id } = question.judge;
        let score = 0;

        switch (question.type) {
            case "choice":
                if (map && map[answer] !== undefined) {
                    score = map[answer];
                } else if (scores && typeof answer === 'string') {
                    // 单选：将答案字母（A, B, C...）转换为索引（0, 1, 2...）
                    const index = answer.charCodeAt(0) - 'A'.charCodeAt(0);
                    score = scores[index] || 0;
                }
                break;
            case "tf":
                if (map && map[answer] !== undefined) {
                    score = map[answer];
                } else if (scores && typeof answer === 'string') {
                    const idx = answer === 'T' ? 0 : 1;
                    score = scores[idx] || 0;
                }
                break;
            case "number":
                if (typeof answer === 'number') {
                    score = answer;
                }
                break;
            case "slider":
                console.warn("Slider type scoring is not supported yet");
                score = 0;
                break;
        }

        return { score_id, score };
    }

    /**
     * 计算所有维度得分
     * @param {Array} validQuestions - 有效题目数组
     * @param {Array} validAnswers - 有效答案数组
     * @returns {Object} 维度得分对象
     */
    calculateDimensionScores(validQuestions, validAnswers) {
        const idToJudge = {};

        // 初始化所有维度
        for (const judge of this.scoreJudge) {
            idToJudge[judge.id] = { content: judge, score: 0 };
        }

        // 计算每个题目的得分
        for (const i in validQuestions) {
            const question = validQuestions[i];
            const answer = validAnswers[i];
            const scoreResult = this.calculateQuestionScore(question, answer);

            if (scoreResult) {
                idToJudge[scoreResult.score_id].score += scoreResult.score;
            }
        }

        return idToJudge;
    }

    /**
     * 根据区间匹配结果
     * @param {Object} idToJudge - 维度得分对象
     * @returns {Object} 匹配结果后的对象
     */
    matchIntervalResults(idToJudge) {
        for (const [key, item] of Object.entries(idToJudge)) {
            const { content, score } = item;
            const intervals = content.intervals;

            let candidates = [];
            if (Array.isArray(intervals) && intervals.length > 0 && typeof intervals[0] === 'object' && intervals[0].condition) {
                const matched = intervals.find((group) => this.evaluateCondition(group.condition));
                candidates = matched ? matched.intervals : [];
            } else if (Array.isArray(intervals)) {
                candidates = intervals;
            }

            const matchInterval = candidates.find((interval) => {
                let [start, end] = interval.interval || [];
                if (start == null || end == null) return false;
                start = start === -1 ? -Infinity : start;
                end = end === -1 ? Infinity : end;
                return score >= start && score <= end;
            });

            if (matchInterval) {
                idToJudge[key].result = matchInterval.result;
            }
        }

        return idToJudge;
    }

    evaluateCondition(condition) {
        if (!condition) return true;
        const factValue = getFact(condition.fact);
        if (factValue == null) return false;
        if (condition.between) {
            const [min, max] = condition.between;
            const low = (min == null) ? -Infinity : min;
            const high = (max == null) ? Infinity : max;
            return factValue >= low && factValue <= high;
        }
        const { op, value } = condition;
        switch (op) {
            case '<=': return factValue <= value;
            case '<': return factValue < value;
            case '>=': return factValue >= value;
            case '>': return factValue > value;
            case '==': return factValue == value;
            case '===': return factValue === value;
            case '!=': return factValue != value;
            case '!==': return factValue !== value;
            default: return false;
        }
    }

    /**
     * 获取总分
     * @param {string} quesName - 问卷名称（如 a1_cognition）
     * @param {Object} idToJudge - 维度得分对象
     * @param {Array} except_ids - 排除的ID数组
     * @returns {Object} 总分对象（包含 reverse 标志，由调用方决定如何应用）
     */
    getScoreFigure(quesName, idToJudge, except_ids = []) {
        if (!quesName) {
            console.error('getScoreFigure requires quesName parameter');
            return null;
        }

        // 从 assessResultConfig 读取 score 配置
        const assessResultConfig = getAssessResult();
        const dimensionId = quesName.split('_')[0]; // 如 a1_cognition -> a1
        
        if (!assessResultConfig || !assessResultConfig[dimensionId]) {
            console.error(`No score config found for ${quesName}`);
            return null;
        }
        
        const scoreFigureConfig = assessResultConfig[dimensionId].score;

        const except_ids_actual = except_ids.length > 0 ? except_ids : (scoreFigureConfig.except ?? []);
        let totalScore = 0;
        
        for (const [key, item] of Object.entries(idToJudge)) {
            if (except_ids_actual.find((id) => id === key) == null) {
                totalScore += item.score;
            }
        }

        const res_total = {
            max: scoreFigureConfig.max,
            score: totalScore,  // 原始分数，不应用 reverse
            reverse: scoreFigureConfig.reverse || false  // 将 reverse 标志传递给调用方
        };

        // 添加偏差值
        if (scoreFigureConfig.bias != null) {
            res_total.score += scoreFigureConfig.bias;
        }

        return res_total;
    }
}
